package cn.bitkit.assist.jdbc;

import cn.bitkit.base.constants.DialectType;
import cn.bitkit.tools.file.ConfigHelper;
import cn.bitkit.base.util.StringUtil;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;

import javax.sql.DataSource;
import java.sql.Connection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 *
 * @author changbo
 * 
 */
@Slf4j
public class JdbcConnection {

	private static final String DEFAULT_DATASOURCE = "spring.datasource";
	private static final Map<String, JdbcConfig> CONFIG_MAP = new ConcurrentHashMap<>();
	private static final Map<String, DataSource> DATA_SOURCE_MAP = new ConcurrentHashMap<>();
	private static String configId = null;

	public static void addDataSource(String datasource) {
		JdbcConfig config = JdbcConfig.builder()
				.id(datasource)
				.driver(ConfigHelper.getValue(datasource+".driver-class-name"))
				.url(ConfigHelper.getValue(datasource+".url"))
				.username(ConfigHelper.getValue(datasource+".username"))
				.password(ConfigHelper.getValue(datasource+".password"))
				.build();
		addDataSource(config);
	}

	public static void addDataSource(JdbcConfig config) {
		if(config.getId() == null){
			config.setId("");
		}
		HikariDataSource ds = new HikariDataSource();
		ds.setDriverClassName(config.getDriver());
		ds.setJdbcUrl(config.getUrl());
		if(StringUtil.hasValue(config.getUsername())){
			ds.setUsername(config.getUsername());
		}
		if(StringUtil.hasValue(config.getPassword())){
			ds.setPassword(config.getPassword());
		}
		CONFIG_MAP.put(config.getId(), config);
		DATA_SOURCE_MAP.put(config.getId(), ds);
	}

	public static void changeConfig(String configId) {
		if(CONFIG_MAP.containsKey(configId)){
			JdbcConnection.configId = configId;
		}
	}

	public static Connection getConnection(){
		try {
			checkDataSource();
			return JdbcConnection.DATA_SOURCE_MAP.get(configId).getConnection();
		} catch (Exception e) {
			log.error("", e);
            throw new RuntimeException("获取数据库连接失败");
		}
	}

	private static void checkDataSource(){
		if(JdbcConnection.configId == null){
			if(CONFIG_MAP.isEmpty()){
				addDataSource(DEFAULT_DATASOURCE);
			}
			JdbcConnection.configId = CONFIG_MAP.keySet().iterator().next();
		}
	}

	public static DialectType getDialectType() {
		checkDataSource();
		String driverClassName = CONFIG_MAP.get(configId).getDriver();
		for(DialectType type : DialectType.values()) {
			if(driverClassName.toLowerCase().contains(type.name().toLowerCase())) {
				return type;
			}
		}
		return null;
	}

}
